package com.ficus.road.maintain.controller;

import com.ficus.road.maintain.core.model.Car;
import com.ficus.road.maintain.core.model.GpsHistory;
import com.ficus.road.maintain.core.model.TheoryGps;
import com.ficus.road.maintain.core.model.Unit;
import com.ficus.road.maintain.core.model.coverage.CoverageFixManualUnit;
import com.ficus.road.maintain.core.model.coverage.CoverageFixTheoryGpsResponse;
import com.ficus.road.maintain.dao.UnitDao;
import com.ficus.road.maintain.dao.coverage.CoverageFixManualDao;
import com.ficus.road.maintain.service.*;
import com.ficus.road.maintain.util.MyDateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * @author xiawen yang
 * @date 2022/4/26 上午11:39
 */
@RestController
public class CoverageFixManualController {
    @Autowired
    private CoverageFixManualService coverageFixManualService;
    @Autowired
    private CycleNumService cycleNumService;
    @Autowired
    private GpsHistoryService gpsHistoryService;
    @Autowired
    private UnitService unitService;
    @Autowired
    private CoverageFixManualDao coverageFixManualDao;
    @Autowired
    private RoadInfoService roadInfoService;
    @Autowired
    private UnitDao unitDao;

    @PostMapping("/coverage/createTheoryGpsManual")
    public ResponseEntity<String> createTheoryGps() {
        coverageFixManualService.createTheoryGps(45);
        return new ResponseEntity<>("success", HttpStatus.OK);
    }

    /**
     * 查看未覆盖路段
     *
     * @param companyId
     * @return
     */
    @GetMapping("/coverage/uncovered/{companyId}")
    public ResponseEntity<List<CoverageFixManualUnit>> queryUncoveredGps(@PathVariable String companyId) {
        List<CoverageFixManualUnit> res = coverageFixManualService.findUncoveredPointSet(cycleNumService.getCurrentCycleNum(), companyId);
        return new ResponseEntity<>(res, HttpStatus.OK);
    }

    /**
     * 补录未覆盖路段
     */
    @PostMapping("/coverage/uncovered/update")
    @PreAuthorize("TODO")
    public ResponseEntity<String> updateUncoveredGps(@RequestBody List<String> idList) {
        // todo: 判断是否能补录
        Date now = new Date();
        // 7点
        Date gpsFixDate = MyDateUtil.getGpsFixDate(now);

        long timestamp = gpsFixDate.getTime() / 1000;

        // 创建新的gps轨迹
        List<TheoryGps> theoryGpsList = coverageFixManualService.queryGpsListByIdList(idList);
        Map<String, List<TheoryGps>> unitIdGpsMap = theoryGpsList.stream().collect(Collectors.groupingBy(TheoryGps::getUnitId));
        unitIdGpsMap.forEach((unitId, gpsList) -> {
            AtomicLong atomic = new AtomicLong(timestamp);
            Car car = unitService.findCarById(unitId);
            gpsList.forEach(item -> {
                GpsHistory gpsHistory = coverageFixManualService.convert2GpsHistory(item, car.getId(), atomic.getAndAdd(2));
                gpsHistoryService.create(gpsHistory);
            });
        });
        // 修改未覆盖路段的状态（补录后算已覆盖了）
        theoryGpsList.parallelStream().forEach(theoryGps -> {
            theoryGps.setIsCovered(Boolean.TRUE);
            coverageFixManualDao.saveOrUpdate(theoryGps);
        });
        return new ResponseEntity<>(null, HttpStatus.OK);
    }

    /**
     * 查看应覆盖轨迹（采样后的轨迹）
     *
     * @param companyId
     * @return
     */
    @GetMapping("/coverage/shouldCover/{companyId}")
    public ResponseEntity<List<CoverageFixTheoryGpsResponse>> queryShouldCoverGps(@PathVariable String companyId) {
        List<CoverageFixTheoryGpsResponse> res = new ArrayList<>();
        Map<String, String> unitIdNameMap = unitDao.findAll().stream().collect(Collectors.toMap(Unit::getId, Unit::getUnitName));
        List<TheoryGps> theoryGpsSamples = coverageFixManualService.findTheoryGpsSamplesByCompany(companyId);
        theoryGpsSamples.stream().collect(Collectors.groupingBy(TheoryGps::getUnitId)).forEach((unitId, gpsList) -> {
            List<CoverageFixTheoryGpsResponse.RoadDetail> roadList = new ArrayList<>();
            gpsList.forEach(item -> {
                CoverageFixTheoryGpsResponse.RoadDetail roadDetail = coverageFixManualService.convert2RoadDetail(item);
                roadList.add(roadDetail);
            });
            CoverageFixTheoryGpsResponse response = CoverageFixTheoryGpsResponse.builder()
                    .unitId(unitId)
                    .unitName(unitIdNameMap.get(unitId))
                    .roadList(roadList)
                    .build();
            res.add(response);
        });
        return new ResponseEntity<>(null, HttpStatus.OK);
    }

    /**
     * 查看实际轨迹
     *
     * @return
     */
    @GetMapping("/coverage/realCover/{companyId}")
    public ResponseEntity<String> queryRealCoverGps() {

        return new ResponseEntity<>(null, HttpStatus.OK);
    }
}
